package com.cfp4cloud.cfp.knowledge.support.handler.parse;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Pair;
import com.cfp4cloud.cfp.knowledge.entity.AiDatasetEntity;
import com.cfp4cloud.cfp.knowledge.entity.AiDocumentEntity;
import com.cfp4cloud.cfp.knowledge.support.constant.FileParserStatusEnums;
import com.cfp4cloud.cfp.knowledge.support.constant.FileTypeEnums;
import com.torchv.infra.unstructured.parser.word.UnstructuredWord;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.InputStream;

@Slf4j
@Service
@RequiredArgsConstructor
public class TorchVUploadFileParseHandler implements UploadFileParseHandler {

	/**
	 * 判断是否支持处理指定类型的文件
	 * <p>
	 * 支持所有常见的Office文档格式，包括旧版（.doc、.ppt、.xls） 和新版（.docx、.pptx、.xlsx）格式。
	 * @param aiDataset 数据集实体
	 * @param documentEntity 文档实体，包含文件信息
	 * @return 如果是支持的Office格式返回true，否则返回false
	 */
	@Override
	public boolean supports(AiDatasetEntity aiDataset, AiDocumentEntity documentEntity) {
		String contentType = FileUtil.extName(documentEntity.getFileUrl());
		return FileTypeEnums.DOC.getType().equals(contentType) || FileTypeEnums.DOCX.getType().equals(contentType);
	}

	/**
	 * 将Office文档转换为纯文本
	 * <p>
	 * 使用Apache POI的DocumentParser解析Office文档，提取其中的文本内容。 该方法会忽略文档的格式信息，只返回纯文本内容。
	 * 如果解析失败，会记录错误日志并返回失败状态。
	 * @param documentEntity 文档实体，包含文档信息
	 * @param inputStream 文件输入流
	 * @param extName 文件扩展名
	 * @return 包含解析状态和文本内容的Pair对象，成功时返回提取的文本，失败时返回错误信息
	 */
	@Override
	public Pair<FileParserStatusEnums, String> file2String(AiDocumentEntity documentEntity, InputStream inputStream,
			String extName) {
		try {
			String content = UnstructuredWord.toMarkdown(inputStream, documentEntity.getName());
			return Pair.of(FileParserStatusEnums.PARSE_SUCCESS, content);
		}
		catch (Exception e) {
			log.error("文件 {} torchv 解析失败", documentEntity.getName(), e);
			return Pair.of(FileParserStatusEnums.PARSE_FAIL, e.getMessage());
		}
	}

	/**
	 * 获取处理器的优先级顺序
	 * <p>
	 * 数值越大，优先级越高。当多个处理器都支持同一文件类型时， 系统会优先使用优先级高的处理器。默认优先级为0。 实现类可以重写此方法来设置自定义优先级。
	 * @return 优先级值，默认返回0
	 */
	@Override
	public int getOrder() {
		return 100;
	}

}
